package com.yc.login.web;

import com.ly.common.bean.Result;
import com.ly.common.biz.BizException;
import com.ly.common.util.CheckUtils;
import com.yc.login.vo.LoginProperties;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.UUID;

@RestController
public class LoginAction {

    @Resource
    LoginProperties properties;

    @RequestMapping("loginProperties")
    LoginProperties loginProperties() {
        return properties;
    }

    @Resource
    JdbcTemplate jdbcTemplate;

    @RequestMapping("login")
    Result login(String username, String password,
                 HttpSession session) throws BizException, ClassNotFoundException,
            InstantiationException, IllegalAccessException {
        CheckUtils.checkEmpty(username, "请填写用户名!");
        CheckUtils.checkEmpty(password, "请填写密码!");
        String sql = "select * from %s where %s=? and %s=?";
        sql = String.format(sql,
                properties.getUserTable(),
                properties.getUsernameColumn(),
                properties.getPasswordColumn());
        Class<?> cls = Class.forName(properties.getUserClass());
        List list = jdbcTemplate.query(sql,
                new BeanPropertyRowMapper(cls), username, password);
        CheckUtils.check(list.isEmpty() || list.size()>1,"用户名或密码错误!");
        Object user = list.get(0);
        session.setAttribute("myinfo", user);
        return Result.success("登录成功!", user);
    }

    @RequestMapping("myinfo")
    public Result myinfo(@SessionAttribute(required = false) Object myinfo){
        if(myinfo == null){
            return Result.failure("未登录", myinfo);
        } else {
            return Result.success("已登录", myinfo);
        }
    }

    @RequestMapping("logout")
    public ModelAndView logout(ModelAndView mav,
                               HttpSession session){
        session.invalidate();
        mav.setViewName("redirect:/");
        return mav;
    }

    // 主工程必须引入 邮箱启动器
    @Resource
    JavaMailSender javaMailSender;

    @GetMapping("forget")
    public Result forget(String username, HttpSession session) throws BizException {
        String sql = "select %s from %s where %s=?";
        sql = String.format(sql
                ,properties.getEmailColumn()
                ,properties.getUserTable()
                ,properties.getUsernameColumn());
        try{
            String email = jdbcTemplate.queryForObject(sql, String.class, username);
            CheckUtils.checkEmpty(email,"当前用户没有设置邮箱地址, 请联系客服!");
            // 生成验证码
            String resetVcode = UUID.randomUUID().toString();
            // 将验证码存入会话
            session.setAttribute("resetVcode", resetVcode);
            // HTML 邮件内容格式
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            mimeMessageHelper.setFrom(properties.getFromEmail());
            mimeMessageHelper.setTo(email);
            mimeMessageHelper.setSubject(properties.getAppName()+"重置密码");
            mimeMessageHelper.setText(
                    "<a href='http://127.0.0.1/reset.html?vcode="+resetVcode+"'>重置密码</a>"
                    ,true);
            javaMailSender.send(mimeMessage);
        }catch (DataAccessException e){
            throw new BizException("没有该账号!",e);
        } catch (MessagingException e) {
            throw new BizException("邮件构建失败!",e);
        }
        return Result.success("重置密码邮件已经发送到您邮箱!", null);
    }

    @ExceptionHandler(BizException.class)
    Result BizExceptionHandle(BizException e){
        e.printStackTrace();
        return Result.failure(e.getMessage(), null);
    }

    @ExceptionHandler(Exception.class)
    Result ExceptionHandle(BizException e){
        e.printStackTrace();
        return Result.failure("业务繁忙,请稍后再试!", null);
    }

}
